import es
import random
import gamethread
import playerlib

import wcs

raceName = "Priestess of the Moon"
race     = wcs.races[raceName]

""" ############################### """
""" ### Begin the configuration ### """
""" ############################### """

config   = race.config()

raceMinLevel     = config.cvar("priestessMinLevel", 50, "The total level required before you are able to play the race.")

config.text("")
config.text("********************")
config.text("Trueshot Aura")
config.text("    All nearby allies have increased")
config.text("    damage.")
config.text("********************")
config.text("")
trueMaxLevel      = config.cvar("trueMaxlevel",       3, "The maximum level of the Trueshot Aura skill") 
trueLevelInterval = config.cvar("trueLevelInterval",  2, "The intervals between the abilities to upgrade their Trueshot Aura skill")

config.text("")
config.text("********************")
config.text("Searing Arrows")
config.text("    The player exchanges some cash to")
config.text("    deal extra damage and set the victim")
config.text("    on fire.")
config.text("********************")
config.text("")
arrowsMaxLevel      = config.cvar("arrowsMaxLevel",       3, "The maximum level of the Searing Arrows skill") 
arrowsLevelInterval = config.cvar("arrowsLevelInterval",  2, "The intervals between the abilities to upgrade their Searing Arrows skill")

config.text("")
config.text("********************")
config.text("Moon Glaive")
config.text("    This skill allows damage")
config.text("    to jump from person to person")
config.text("    each time the damage decreasing.")
config.text("********************")
config.text("")
moonMaxLevel      = config.cvar("moonMaxLevel",       5, "The maximum level of the Moon Glaive skill") 
moonLevelInterval = config.cvar("moonLevelInterval",  1, "The intervals between the abilities to upgrade their Moon Glaive skill")

config.text("")
config.text("********************")
config.text("Star Fall")
config.text("    Holding your ultimate down")
config.text("    will cause waves of attacks to")
config.text("    damage nearby enemies.")
config.text("********************")
config.text("")
starMinLevel      = config.cvar("starMinLevel",       6, "The level required before a player can acquire level 1 of the Star Fall skill.")
starMaxLevel      = config.cvar("starMaxLevel",       3, "The maximum level of the Star Fall skill") 
starLevelInterval = config.cvar("starLevelInterval",  4, "The intervals between the abilities to upgrade their Star Fall skill")

config.load(True)

""" ##################### """
""" ### END OF CONFIG ### """
""" ##################### """

race.registerSkill("Trueshot Aura",  int(trueMaxLevel),   int(trueLevelInterval),   "Yourself and all nearby allies have increased damage.")
race.registerSkill("Searing Arrows", int(arrowsMaxLevel), int(arrowsLevelInterval), "Your hits deal extra damage and set fire to the target in exchange for some cash.")
race.registerSkill("Moon Glaive",    int(moonMaxLevel),   int(moonLevelInterval),   "You attacks jump from target to target, each jump lessens the damage.")
race.registerUltimate("Star Fall",    int(starMinLevel),   int(starMaxLevel), int(starLevelInterval), "Hold your ultimate to deal damage to all near by oppents.")

race.registerMinLevel(int(raceMinLevel))

race.registerWeaponRestriction("block only", "m3", "xm1014")
    
def player_hurt(event_var):
    """
    Executed when a player is hurt. We shall have to test a couple of things
    here; firstly, if the attacker has the Moon Glaive spell then damage a
    random player within the area around the victim, reducing the damage done.
    Secondly, we will need to test if the player has enough cash to support
    the searing arror ability, if so, burn their victims. Thirdly, if the 
    attacker is within range of a player with the Trueshot Aura active, then
    buff their damage by 10% multiplied by the player's level.
    """
    userid = int(event_var["userid"])
    attacker = int(event_var["attacker"])
    wcsUserid = wcs.players[userid]
    wcsAttacker = wcs.players[attacker]
    if attacker:
        attackerPlayer = playerlib.getPlayer(attacker)
        damage = wcs.getDamage(event_var)
        glaive = wcsAttacker[raceName]["Moon Glaive"]
        if glaive:
            team = es.getplayerteam(attacker)
            filt = "#ct" if team == 2 else "#t"
            x, y, z = es.getplayerlocation(userid)
            plist = wcsUserid.getNearCoordList(x, y, z, 120, 120, 120, filt)
            if plist:
                choice = random.choice(plist)
                wcs.players[choice].damage(damage / 2, 32, attacker)
                #wcs.effect.Beam2(userid, choice, 1.5, 128, 42, 42)
        searing = wcsAttacker[raceName]["Searing Arrows"]
        if searing:
            cash = wcsAttacker.getCash()
            if cash >= (searing * 10):
                attackerPlayer.setCash(cash - searing * 10)
                wcsUserid.burn(1)
                wcsUserid.damage(searing * 3, 32, attacker)
        
        maxAuraBonus = None
        team = int(event_var["es_attackerteam"])
        target_x, target_y, target_z = es.getplayerlocation(attacker)
        for player in filter(lambda x: es.getplayerteam(x) == team, es.getUseridList()):
            x, y, z = es.getplayerlocation(player)
            if ((target_x - x) ** 2 + (target_y - y) ** 2 + (target_z - z) ** 2) ** 0.5 <= 300:
                auraLevel = wcs.players[player][raceName]["Trueshot Aura"]
                if auraLevel:
                    maxAuraBonus = max(auraLevel * 0.1, maxAuraBonus) if maxAuraBonus is not None else auraLevel * 0.1
        if maxAuraBonus is not None:
            wcsUserid.damage(int(damage * maxAuraBonus), 32, attacker)
            
def player_ultimate_on(event_var):
    """
    Executed when a player's ultimate is activated (the key pressed down).
    Freeze the player and begin the delay to hurt all enemies within a certain
    range.
    """
    userid = event_var["userid"]
    player = wcs.players[userid]
    starfall = player[raceName]["Star Fall"]
    if starfall:
        player["starFalling"] = True
        player.freeze()
        player.delayedName(starfall * 15, "starFallCancel", ultiOff, userid)
        starLoop(userid)
        
def starLoop(userid):
    """
    Executed each time a star fall tick executes. For each player in range,
    ensure that we damage them by a given amount.
    
    @param int userid The ID of the user who is casting the command
    """
    player = wcs.player[userid]
    if player["starFalling"]:
        #wcs.effect.Ring2(userid, 50, 1.6, 191, 62, 255)
        #wcs.effect.Misc1(userid, 1.6)
        filt = "#ct" if es.getplayerteam(userid) == 2 else "#t"
        player.near(800, starTarget, filt)
        player.delayed(1.5, "starFall", starLoop, userid)
        
def starTarget(userid, attacker):
    """
    This fucntion is executed for every enemy in range of the attacker who is
    currently casting the start falling. Simple damage the victim.
    
    @param int userid The ID of the user we wish to damage
    @param int attacker The ID of the person casting the star falling skill
    """
    wcs.players[userid].damage(50, 32, attacker)
        
def player_ultimate_off(event_var):
    """
    Executed when the player releases their ultimate key. If the player hasn't
    had the 15 second forced release, then turn the ultimate off now.
    """
    userid = int(event_var["userid"])
    player = wcs.players[userid]
    if "starFalling" in player:
        ultiOff(userid)
        
def ultiOff(userid):
    """
    Executed when we wish to stop a player from channelling the star fall
    skill. Simply cancel the delay, and unfreeze them.
    """
    player = wcs.players[userid]
    player.cancelDelayed("starFallCancel")
    player.cancelDelayed("starFall")
    if player["starFalling"]:
        player.unFreeze()
        del player["starFalling"]